package cn.virens.common.util.components.pool;

import cn.virens.common.util.core.Assert;
import cn.virens.common.util.exception.APIException;
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;

public class VirObjectPool<K, V> extends GenericKeyedObjectPool<K, V> {

    public VirObjectPool(VirObjectPoolFactory<K, V> factory) {
        super(new VirObjectPoolFactoryWarp<>(factory));
    }

    /**
     * 将对应的KEY值与别名进行绑定
     *
     * @param key   KEY值
     * @param alias 别名值
     */
    public void bindAlias(K key, String alias) {
        getFactory().bindAlias(key, alias);
    }

    /**
     * 根据KEY值，解除与别名的绑定关系
     *
     * @param key KEY值
     * @throws APIException
     */
    public void unbindAliasWithKey(K key) throws APIException {
        getFactory().unbindAliasWithKey(Assert.isNull(key));
    }

    /**
     * 根据别名，解除与KEY值的绑定关系
     *
     * @param alias 别名值
     * @throws APIException
     */
    public void unbindKeyWithAlias(String alias) throws APIException {
        getFactory().unbindKeyWithAlias(Assert.isNull(alias));
    }

    /**
     * 根据别名从对象池中获取对象
     *
     * @param alias 别名值
     * @return 对象
     * @throws Exception
     */
    @SuppressWarnings("deprecation")
    public V borrowObject0(String alias) throws Exception {
        return borrowObject0(alias, getMaxWaitMillis());
    }

    /**
     * 根据别名从对象池中获取对象
     *
     * @param alias               别名值
     * @param borrowMaxWaitMillis 等待超时
     * @return 对象
     * @throws Exception
     */
    public V borrowObject0(String alias, long borrowMaxWaitMillis) throws Exception {
        return borrowObject(getKeyWithAlias(alias), borrowMaxWaitMillis);
    }

    /**
     * 根据别名获取对应的KEY值
     *
     * @param alias 别名值
     * @return KEY值
     * @throws APIException
     */
    public K getKeyWithAlias(String alias) throws APIException {
        return getFactory().getKeyWithAlias(Assert.isNull(alias));
    }

    /**
     * 根据KEY值获取对应的别名值
     *
     * @param key KEY值
     * @return 别名值
     * @throws APIException
     */
    public String getAliasWithKey(K key) throws APIException {
        return getFactory().getAliasWithKey(Assert.isNull(key));
    }

    @Override
    public VirObjectPoolFactoryWarp<K, V> getFactory() throws APIException {
        return (VirObjectPoolFactoryWarp<K, V>) super.getFactory();
    }

}
